#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int MOD;
int a[N];
struct Oper{
    int l,r,a,b;
    friend bool operator<(Oper a,Oper b){
        return a.r < b.r;
    }
};
struct OperPart{
    int a,b;
    friend OperPart operator+(OperPart a,OperPart b){
        return {(int)(1ll*a.a*b.a%MOD),(int)(1ll*a.b*b.a%MOD + b.b)%MOD};
    }
    OperPart& operator+=(OperPart va){
        b = (1ll*b*va.a%MOD + va.b)%MOD;
        a = 1ll*va.a*a%MOD;
        return *this;
    }
};
struct segment_tree{
    struct Tnode{
        OperPart tag;
        int ls,rs;
        int L,R;
    };
    vector<Oper> val[N<<2];
    int build_temp_tree(vector<Tnode> &tt,int l,int r){
        if(l == r){
            return l;
        }
        int mid = (l + r)/2;
        int lson = build_temp_tree(tt,l,mid);
        int rson = build_temp_tree(tt,mid+1,r);
        tt.push_back({{1,0},lson,rson,tt[l].L,tt[r].R});
        return tt.size() - 1;
    }
    void Tpush_down(vector<Tnode> &tt,int now){
        tt[tt[now].ls].tag += tt[now].tag;
        tt[tt[now].rs].tag += tt[now].tag;
        tt[now].tag = {1,0};
    }
    void Tupdate(vector<Tnode> &tt,int now,int x,int y,OperPart v){
        if(x > tt[now].R || y < tt[now].L){
            return;
        }
        if(x <= tt[now].L && tt[now].R <= y){
            tt[now].tag += v;
            return;
        }
        Tpush_down(tt,now);
        Tupdate(tt,tt[now].ls,x,y,v);
        Tupdate(tt,tt[now].rs,x,y,v);
    }
    void Tpush_down_all(vector<Tnode> &tt,int now){
        if(tt[now].ls >= 0){
            Tpush_down(tt,now);
            Tpush_down_all(tt,tt[now].ls);
            Tpush_down_all(tt,tt[now].rs);
        }
    }
    void build_node(int now){
        vector<int> pos;
        for(Oper op : val[now]){
            pos.push_back(op.l);
            pos.push_back(op.r);
        }
        sort(pos.begin(),pos.end());
        pos.erase(unique(pos.begin(),pos.end()),pos.end());
        vector<pair<int,int>> segments;
        for(int ps : pos){
            segments.push_back(make_pair(ps,ps));
        }
        for(int i = 1;i < pos.size();i++){
            if(pos[i] - 1 >= pos[i - 1] + 1){
                segments.push_back(make_pair(pos[i - 1] + 1,pos[i] - 1));
            }
        }
        sort(segments.begin(),segments.end());
        vector<Tnode> tt;
        for(pair<int,int> s : segments){
            tt.push_back({{1,0},-1,-1,s.first,s.second});
        }
        int rot = build_temp_tree(tt,0,tt.size() - 1);
        for(Oper op : val[now]){
            Tupdate(tt,rot,op.l,op.r,{op.a,op.b});
        }
        Tpush_down_all(tt,rot);
        val[now].clear();
        for(Tnode nd : tt){
            if(nd.ls >= 0){
                break;
            }
            val[now].push_back({nd.L,nd.R,nd.tag.a,nd.tag.b});
        }
    }
    void update(int now,int l,int r,int p,Oper vl){
        val[now].push_back(vl);
        if(r == p){
            build_node(now);
        }
        if(l == r){
            return;
        }
        int mid = (l + r)/2;
        if(p <= mid){
            update(now<<1,l,mid,p,vl);
        }else{
            update(now<<1|1,mid+1,r,p,vl);
        }
    }
    OperPart query(int now,int l,int r,int x,int y,int k){
        if(x <= l && r <= y){
            auto p = lower_bound(val[now].begin(),val[now].end(),(Oper){k,k,1,0});
            if(p == val[now].end()){
                return {1,0};
            }else if(p->l > k){
                return {1,0};
            }else{
                return {(int)(p->a),(int)(p->b)};
            }
        }
        int mid = (l + r)/2;
        OperPart pt = {1,0};
        if(x <= mid){
            pt += query(now<<1,l,mid,x,y,k);
        }
        if(mid < y){
            pt += query(now<<1|1,mid+1,r,x,y,k);
        }
        return pt;
    }
}sg;
int main(){
    int typ;
    cin>>typ;
    int n;
    cin>>n>>MOD;
    for(int i = 1;i<=n;i++){
        cin>>a[i];
    }
    int q;
    cin>>q;
    int cur = 0;
    int lastans = 0;
    for(int i = 1;i<=q;i++){
        int op;
        cin>>op;
        if(op == 1){
            int l,r,a,b;
            cin>>l>>r>>a>>b;
            if(typ&1){
                l ^= lastans;
                r ^= lastans;
            }
            sg.update(1,1,min(q,100000),++cur,{l,r,a,b});
        }else if(op == 2){
            int l,r,k;
            cin>>l>>r>>k;
            if(typ&1){
                l ^= lastans;
                r ^= lastans;
                k ^= lastans;
            }
            OperPart op = sg.query(1,1,min(q,100000),l,r,k);
            lastans = (1ll*a[k]*op.a%MOD + op.b)%MOD;
            cout<<lastans<<'\n';
        }
    }
}